/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-12     RT-Thread    first version
 */
#include <board.h>
#include <rtthread.h>
#include <rtdevice.h>
#define UART_NAME "uart1"
#ifndef LED_PIN1
#define LED_PIN1 GET_PIN(A, 8)
#endif
#ifndef LED_PIN2
#define LED_PIN2 GET_PIN(D, 2)
#endif

#ifndef BTN_PIN1
#define BTN_PIN1 GET_PIN(A, 13)
#endif
#ifndef BTN_PIN2
#define BTN_PIN2 GET_PIN(A, 15)
#endif

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

static struct rt_semaphore rx_sem;
static struct rt_semaphore btn_sem;

static rt_device_t serial;

static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&rx_sem);
    return RT_EOK;
}

static void serial_thread_entry(void *parameter)
{
    char ch;
    while (1)
    {
        while (rt_device_read(serial, -1, &ch, 1) != 1)
        {
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        }
        ch = ch + 1;
        rt_device_write(serial, 0, &ch, 1);
    }
}

static int serial_sample(void)
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    char str[] = "hello Rt-thread\r\n";
    rt_strncpy(uart_name, UART_NAME, RT_NAME_MAX);
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", uart_name);
        return RT_ERROR;
    }
    else
    {
        rt_kprintf("find %s OK\n", uart_name);
    }
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
    rt_device_open(serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
    rt_device_set_rx_indicate(serial, uart_input);
    rt_device_write(serial, 0, str, sizeof(str) - 1);
    rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 20, 10);
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        ret = RT_ERROR;
    }
    return ret;
}

void led_thread1(void *args)
{
    while (1)
    {
        rt_pin_write(LED_PIN1, PIN_LOW);
        rt_thread_delay(2000);
        rt_pin_write(LED_PIN1, PIN_HIGH);
        rt_thread_delay(300);
    }
}
void led_thread2(void *args)
{
    while (1)
    {
        rt_pin_write(LED_PIN2, PIN_LOW);
        rt_thread_delay(200);
        rt_pin_write(LED_PIN2, PIN_HIGH);
        rt_thread_delay(3000);
    }
}

static int led_sample(void)
{
    rt_err_t ret = RT_EOK;
    rt_pin_mode(LED_PIN1, PIN_MODE_OUTPUT);
    rt_pin_write(LED_PIN1, PIN_HIGH);
    rt_pin_mode(LED_PIN2, PIN_MODE_OUTPUT);
    rt_pin_write(LED_PIN2, PIN_HIGH);
    rt_thread_t lt1 = rt_thread_create("LED1", led_thread1, RT_NULL, 256, 19, 100);
    if (lt1 != RT_NULL)
    {
        rt_thread_startup(lt1);
        rt_kprintf("Thread LED1 startup!\r\n");
    }
    else
    {
        ret = RT_ERROR;
    }
    rt_thread_t lt2 = rt_thread_create("LED2", led_thread2, RT_NULL, 256, 19, 100);
    if (lt2 != RT_NULL)
    {
        rt_thread_startup(lt2);
        rt_kprintf("Thread LED2 startup!\n\r");
    }
    else
    {
        ret = RT_ERROR;
    }
    return ret;
}

static void led0_thread_entry(void* parameter)
{
    rt_err_t err;
    static int flag=0;
    while (1)
    {
        err = rt_sem_take(&btn_sem, RT_WAITING_FOREVER);
        if (err == RT_EOK)
        {
            if(flag==0)
            {
                rt_pin_write(LED_PIN1, PIN_LOW);
                flag=1;
            }
            else
            {
                rt_pin_write(LED_PIN1, PIN_HIGH);
                flag=0;
            }
            rt_kprintf("led thread: sem take ok!\r\n");
        }
        else
        {
            rt_kprintf("led thread: sem take error!\r\n");
        }
    }
}
static void key_scan_thread_entry(void* parameter)
{
    rt_uint8_t key;
    rt_err_t err;

    while (1)
    {
        key = rt_pin_read(BTN_PIN1);
        if (key == PIN_LOW)
        {
            rt_kprintf("key_scan_thread: key0 pressed!\r\n");
            err = rt_sem_release(&btn_sem);
            if (err != RT_EOK)
            {
                rt_kprintf("key_scan_thread: sem released error!\r\n");
            }
            else
            {
                rt_kprintf("key_scan_thread: sem released ok!\r\n");
            }
        }
        rt_thread_delay(10);
    }

}

static int btn_led_sample(void)
{
    rt_thread_t tid1 = RT_NULL;
    rt_thread_t tid2 = RT_NULL;
    rt_pin_mode(BTN_PIN1,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(LED_PIN1,PIN_MODE_OUTPUT);
    rt_pin_write(LED_PIN1, PIN_HIGH);
    rt_err_t result = 0;
    result = rt_sem_init(&btn_sem, "btnsem", 0, RT_IPC_FLAG_FIFO);
    tid1 = rt_thread_create("t1", key_scan_thread_entry, RT_NULL, 512, 1, 20);
    if (tid1 != RT_NULL)
    {
        rt_thread_startup(tid1);
    }
    else
    {
        return result;
    }
    tid2 = rt_thread_create("led0", led0_thread_entry, RT_NULL, 512, 3, 20);
    if (tid2 != RT_NULL)
    {
        rt_thread_startup(tid2);
    }
    else
    {
        return result;
    }
    return result;
}
int main(void)
{

}
MSH_CMD_EXPORT(serial_sample, uart device sample);
MSH_CMD_EXPORT(led_sample, led device sample);
MSH_CMD_EXPORT(btn_led_sample, btn_led device sample);

